﻿<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Движение по касательной</title>
<link rel="stylesheet" type="text/css" href="../lib/styles.css"/>
<script type="text/javascript" src="../lib/html.js"></script>
<script type="text/javascript" src="../lib/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="../lib/raphael-min.js"></script>
<script type="text/javascript">
	$(function(){
		var panel = $("#paper1");
			paper = new Raphael(panel[0]),
			duration = 10000;

		var color = {path:"#888", point:"#008", dirMarker:"#f00", point:"#f00"},
			origin = {x:panel.width()/2, y:panel.height()/2};
			
		Vector = {
			length: function(x1, y1, x2, y2){
				return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
			},
			point: function(origin, alpha, length){
				return {
					x:length*Math.cos(alpha*Math.PI/180)+origin.x,
					y:length*Math.sin(alpha*Math.PI/180)+origin.y
				};
			}, 
			angle: function(pt1, pt2){
				return Math.atan((pt2.y - pt1.y)/(pt2.x - pt1.x))*180/Math.PI + 30;
			}
		};
		

		
		var svnPath = "M 200, 200, Q 240, 210, 300, 300 Q 340, 320, 400, 300, Q 470, 200, 380, 150, Q 250, 80, 240, 120, Q 220, 140, 210, 180";

		
		var path = paper.path(svnPath).attr({stroke:color.path});
		var lng = path.getTotalLength();
		var nPoints = 10, 
			step = lng/nPoints;
		for(var i=0; i<nPoints; i++){
			var pt = path.getPointAtLength(step*i);
			paper.circle(pt.x, pt.y, 3).attr({"stroke-width":0, fill:color.point});
			
			var alpha = Math.round(pt.alpha);
			var alphaN = Math.round(pt.alpha%180);
			
			var angle = alphaN>180?alphaN:alphaN>90?alphaN-180:alphaN<-90?alphaN+180:alphaN;
			
			var tng = Vector.point(pt, alpha, 25);
			paper.path(["M", pt.x, pt.y, "L", tng.x, tng.y]).attr({stroke:color.dirMarker});
		}
		
		
		var buglet = paper.path("M -10, 5 L 5, 5 L 10, 0, L 5,-5 L -10, -5, L -5, 0 Z").attr({stroke:"#008"});
		buglet.transform("T 200, 200");
		buglet.direction = 0;
		
		var cntt =0;
		paper.customAttributes.progress = function (v) {
			var path = this.data("mypath"),
				attrs = this.attr(),
				offset = { x: 0, y: 0 };

			if (!path) return{transform: "t0,0"};
			
			if (attrs.hasOwnProperty("width")) {
				offset.x = -this.attr("width") / 2;
				offset.y = -this.attr("height") / 2;
			}
			
			var len = path.getTotalLength();
			var point = path.getPointAtLength(v * len);

			// нормализация угла касательной
			var angle = point.alpha % 360;
			// если касательная развернута назад, учитываем это
			var newDirection = Math.abs(this.direction - angle)>340?angle:
								Math.abs(this.direction - angle)>120?angle-180:
								angle;
			
			this.direction = newDirection;
			
			return {
				transform: "t" + (point.x + offset.x) + "," + (point.y + offset.y) + 
				"r" + this.direction
			};
		};
		
		buglet.data("mypath", path);
		buglet.attr("progress", 0);
		buglet.animate({ progress: 1 }, duration);
		
	});
</script>
</head>
<body>
	<h1>Движение по касательной</h1>
	<p>Движение по кривой с ориентацией по касательной.</p>
	<p>Особенности:</p>
	<ul>
		<li>Вектор касательной может быть направлен как вперед по ходу объекта, так и назад. Важно сохранить ориентацию объекта</li>
	</ul>
	
	<div id="out" class="out code"></div>
	<div id="paper1" class="paper" style="width:800px; height:600px;">
	</div>
	

</body>
</hmtl>